JPEG编解码原理

您所在的位置:网站首页 jpg dct JPEG编解码原理

JPEG编解码原理

2023-03-31 12:06| 来源: 网络整理| 查看: 265

1.背景介绍

问题定义:为什么要做视频图像的编解码?

我们先来看看,视频资源占用计算:4KP30视频1min,3840*2180*3*30*60* = 42.7GB(每帧大小24.3MB),1分钟4K的视频大概需要42.7GB存储,因此视频图像的编解码十分必要。

我们再看看图像的存储格式和常用分辨率:

模拟信号PAL、NTSC制式已经远去,我们来看数字信号(YUV、RGB888),由于人眼对亮度信号比色度信号更敏感,因此出现了YUV(planar/semi planar)降采样格式:YUV420、YUV422、YUV444

图1 降采样格式,实心点为Y分量,空心圆圈为cb、cr分量图2 平面格式与交错格式内存存储2.编解码方法

参考经典数字图像处理教材,常见的编解码方法主要做以下三方面工作:

时间/空间冗余,利用时间空间相关性消除编码冗余,通过变长编码(直方图越大的值,分配较小的比特)不相关信息,忽略人眼不敏感的信息

如下图,这张图有大量的平坦区域(空间冗余),并且灰度集中在几个区间(编码冗余)

图3 冗余分析

基本上述分析,如何来从上述三个方面来压缩图像呢?基于两个先验:

人眼对亮度分量的敏感度高于色度分量,轻微的色度变化对视觉体验影响很小人眼对低频分量的敏感度高于高频分量,轻微的高频变化对视觉体验影响很小

常见的编解码流程如下:

图3 常见的codec流程3.JPEG编解码

目前有较多的图像编码标准,如jpeg、bmp、gif、png、webp、heif,我们这里先说jpeg部分,这个编解码标准诞生于20世纪90年代,JPEG标准仅仅说明定义了codec部分,也就是图片如何压缩为字节流以及重新解码为图片的过程,标准没有涉及到文件的存储格式。

1992年颁布了JPEG File Interchange Format(JFIF),目前在互联网上用的最多的jpeg格式,接着又出现了EXIF格式,主要用于数码产品,记录了媒体的时间地点信息。

JPEG文件由一系列字段组成,每个字段都有marker(标记),由0xff开头。

图4 jpeg字段

(1)SOF marker(Start of Frame),这个字段定义了文件的起始

图5 SOF字段

(2)APP0(Application-specific),这个字段定义了JFIF格式

图6 APP0字段(定义JFIF格式)

(3)APPn(Application-specific),定义了其它格式,如APP1表示exif格式

图7 定义APPn字段

(4)DQT(Define Quantization Table(s)),定义了量化表

图8 字义量化表字段

下面以jpeg图的二进制数据来分析,通过vim打开后(:%!xxd切换到十六进制),ffd8表示start of image,ffe0表示app0,即是JFIF格式,0043前面的ffdb表示量化表(两个ffdb分别表示亮度和色度分量的量化表),0043表示量化表65字节(64byte量化参数 + 1 byte精度及量化表ID),ffc0表示start of frame,即图像数据

图9 jpeg字段分析4.jpeg编解码流程

jpeg编码流程如下:

图10 jpeg编解码流程(1)块划分

将输入数据按8x8划分数据块,源图像如果不是8x8的整数倍,需进行补充

图11 块划分(2)DCT变换

减去128再进行DCT,DCT可接受的范围是[-128,127)

DCT变换,得到64个基底系数,(0,0)位置是直流系数,是64个源数据的均值

DCT在复杂度和失真上是最好的trade-off

我们暂时先只考虑水平方向上一行数据(8个像素)的情况时的DCT变换,从而来说明其物理意义。如下图所示:

原始的图像信号(最左边的波形)经过DCT变换之后变成了8个波,其中第一个波为直流成分,其余7个为交流成分。由于大多数图像的高频分量比较小,相应的图像高频分量的DCT系数经常接近于0,再加上高频分量中只包含了图像的细微的细节变化信息,而人眼对这种高频成分的失真不太敏感,所以,可以考虑将这一些高频成分予以抛弃,从而降低需要传输的数据量。这样一来,传送DCT变换系数的所需要的编码长度要远远小于传送图像像素的编码长度。到达接收端之后通过反离散余弦变换就可以得到原来的数据,虽然这么做存在一定的失真,但人眼是可接受的,而且对这种微小的变换是不敏感的。

图12 DCT变换分解图(3)量化

对亮度和色度分量的DCT系数进行量化,使用如下量化表,该量化表是从广泛的实验中得出的。当然,也可以自定义量化表

//标准亮度分量量化表 static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = { 16, 11, 10, 16, 24, 40, 51, 61, 12, 12, 14, 19, 26, 58, 60, 55, 14, 13, 16, 24, 40, 57, 69, 56, 14, 17, 22, 29, 51, 87, 80, 62, 18, 22, 37, 56, 68, 109, 103, 77, 24, 35, 55, 64, 81, 104, 113, 92, 49, 64, 78, 87, 103, 121, 120, 101, 72, 92, 95, 98, 112, 100, 103, 99 }; //标准色度分量量化表 static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = { 17, 18, 24, 47, 99, 99, 99, 99, 18, 21, 26, 66, 99, 99, 99, 99, 24, 26, 56, 99, 99, 99, 99, 99, 47, 66, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 };

量化表搞掉了很多高频量,对DCT变换进行量化后得到量化结果,会出现大量的0,使用Z形扫描,可以将大量的0连到一起,减小编码后的大小。越偏离左上方,表示频率越高,这里其实是通过量化,将图像的高频信息干掉了。

图13 Z形编码(4)DC和AC分量编码

DC进行DPCM编码,AC进行RLC编码,这两种编码都有中间格式,进一步减小存储量,原理可自行wiki

(5)熵编码

在得到DC系数的中间格式和AC系数的中间格式之后,为进一步压缩图像数据,有必要对两者进行熵编码,通过对出现概率较高的字符采用较小的bit数编码达到压缩的目的。JPEG标准具体规定了两种熵编码方式:Huffman编码和算术编码。JPEG基本系统规定采用Huffman编码。

Huffman编码:对出现概率大的字符分配字符长度较短的二进制编码,对出现概率小的字符分配字符长度较长的二进制编码,从而使得字符的平均编码长度最短。Huffman编码的原理请参考数据结构中的Huffman树或者最优二叉树。

Huffman编码时DC系数与AC系数分别采用不同的Huffman编码表,对于亮度和色度也采用不同的Huffman编码表。因此,需要4张Huffman编码表才能完成熵编码的工作。具体的Huffman编码采用查表的方式来高效地完成。然而,在JPEG标准中没有定义缺省的Huffman表,用户可以根据实际应用自由选择,也可以使用JPEG标准推荐的Huffman表。或者预先定义一个通用的Huffman表,也可以针对一副特定的图像,在压缩编码前通过搜集其统计特征来计算Huffman表的值。

下一篇再来讲jpeg编解码库libjpeg turbo的使用。

5.参考

[1] JPEG - Wikipedia

[2] https://blog.csdn.net/carson2005/article/details/7753499



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3